
local raw = ...
local raw_resource = raw.resource
local raw_play = raw.play
local registry = raw.registry

local io_open = io.open
local getmetatable, setmetatable = raw.getmetatable, raw.setmetatable
local pcall = pcall
local getfenv,setfenv = raw.getfenv, raw.setfenv
local error = error

local function constant(value)
	return function()  return value;  end
end

local channel_sound_mapping = {}
registry["channel_sound_mapping"] = channel_sound_mapping

local channel_meta do

	local channel_getters = {
		hz = raw.getchannelhz;
		audibility = raw.getchannelaudibility;
		muted = raw.getchannelmuted;
		paused = raw.getchannelpaused;
		pan = raw.getchannelpan;
		volume = raw.getchannelvolume;
		playing = raw.getchannelplaying;
		stop = constant(raw.stopchannel);
	}
	
	local channel_setters = {
		hz = raw.setchannelhz;
		muted = raw.setchannelmuted;
		paused = raw.setchannelpaused;
		pan = raw.setchannelpan;
		volume = raw.setchannelvolume;
	}

	channel_meta = {
		__tostring = raw.channelsummary;
		__index = function(self, key)
			local getter = channel_getters[key]
			if getter then
				return getter(self)
			end
			local extravars = getfenv(self)
			if extravars then
				return extravars[key]
			end
			return nil
		end;
		__newindex = function(self, key, value)
			local setter = channel_setters[key]
			if setter then
				return setter(self, value)
			end
			if channel_getters[key] then
				error('attempt to set read-only field "' .. key .. '"', 2)
			end
			local extravars = getfenv(self)
			if not extravars then
				extravars = {}
				setfenv(self, extravars)
			end
			extravars[key] = value
		end;
	}

end

local sound_meta do

	local sound_getters = {
		play = constant(function(self)
			local channel, channel_index = raw_play(self);
			channel_sound_mapping[channel_index] = self;
			return setmetatable(channel, channel_meta);
		end);
	}

	local sound_setters = {
	}

	sound_meta = {
		__gc = raw.destroysound;
		__tostring = raw.soundsummary;
		__index = function(self, key)
			local getter = sound_getters[key]
			if getter then
				return getter(self)
			end
			local extravars = getfenv(self)
			if extravars then
				return extravars[key]
			end
			return nil
		end;
		__newindex = function(self, key, value)
			local setter = sound_setters[key]
			if setter then
				return setter(self, value)
			end
			if sound_getters[key] then
				error('attempt to set read-only field "' .. key .. '"', 2)
			end
			local extravars = getfenv(self)
			if not extravars then
				extravars = {}
				setfenv(self, extravars)
			end
			extravars[key] = value
		end;
	}
	
end


return {

	update = raw.update;
	resource = function(res)
		res = raw_resource(res)
		return setmetatable(res, sound_meta)
	end;
	wavedata = raw.wavedata;
	
}
